﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;

namespace WorkStation.Frameworks.Core.Data.Linq
{
    public static class ExpressionExtensions
    {
        public static Expression<Func<T, bool>> CreateTrueOriginalExpression<T>() 
        {
            return v => true;
        }

        public static Expression<Func<T, bool>> CreateFalseOriginalExpression<T>() 
        {
            return v => false;
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) 
        {
            ComposeExpressionTool tool = new ComposeExpressionTool(left, right, Expression.AndAlso);

            return tool.ComposeExpression() as Expression<Func<T, bool>>;
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) 
        {
            ComposeExpressionTool tool = new ComposeExpressionTool(left, right, Expression.OrElse);

            return tool.ComposeExpression() as Expression<Func<T, bool>>;
        }

        public static MemberInfo GetMemberInfo<T, TProperty>(this Expression<Func<T, TProperty>> expression) 
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess) 
            {
                throw new Exception("错误的表达式输入，请输入(criteria => criteria.Id)等属性成员表达式");
            }
          
            return (expression.Body as MemberExpression).Member;
        }

        public static MemberInfo TryGetMemberInfo<T, TProperty>(this Expression<Func<T, TProperty>> expression) 
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess) 
            {
                return null;
            }

            return (expression.Body as MemberExpression).Member;
        }

        public static string GetSQLFromExpressionType(ExpressionType type)
        {
            switch (type)
            {
                case ExpressionType.AndAlso:
                    return "AND";
                case ExpressionType.OrElse:
                    return "OR";
                case ExpressionType.Equal:
                    return "=";
                case ExpressionType.NotEqual:
                    return "<>";
                case ExpressionType.GreaterThan:
                    return ">";
                case ExpressionType.GreaterThanOrEqual:
                    return ">=";
                case ExpressionType.LessThan:
                    return "<";
                case ExpressionType.LessThanOrEqual:
                    return "<=";
                default:
                    return string.Empty;
            }
        }
    }
}
